iT邦幫忙

2025 iThome 鐵人賽

DAY 19
0

檔案上傳系統 — 多格式文件的智能上傳機制 (6)

在前五篇,我們建構了完整的內容生成系統,今天我們要探討智能助手的「檔案處理入口」:檔案上傳系統

這個系統能夠處理多種格式的檔案,通過本地 API 服務實現強大的檔案解析能力,並建立完整的狀態管理機制為後續的智能分析做準備。


功能簡介

檔案上傳系統提供:

  • 多格式檔案支援:透過本地 API 服務支援 txt、docx、pdf 等多種格式
  • 智能檔案驗證:自動檢查檔案有效性和路徑正確性
  • 本地 API 整合:與 FastAPI 服務無縫對接,支援二進位檔案上傳
  • 完整狀態管理:自動保存檔案內容和metadata供後續處理
  • 錯誤處理機制:提供詳細的錯誤資訊和恢復建議

核心程式碼解析

檔案上傳工具主函數

def upload_file_tool(self, file_path: str) -> str:
    """上傳檔案並分兩階段處理"""
    print(f"[DEBUG] ===== upload_file_tool 被調用了! =====")
    print(f"[DEBUG] 檔案路徑: '{file_path}'")
    
    try:
        if not file_path or not Path(file_path).exists():
            return "檔案路徑無效或檔案不存在"
        
        filename = Path(file_path).name
        print(f"[DEBUG] 準備上傳檔案: {filename}")
        
        with open(file_path, 'rb') as file:
            files = {'file': (filename, file, 'application/octet-stream')}
            print(f"[DEBUG] 發送請求到API...")
            response = requests.post(f"{LOCAL_API_BASE}/upload-file", files=files, timeout=30)
            
            print(f"[DEBUG] API響應狀態碼: {response.status_code}")
            print(f"[DEBUG] API響應內容: {response.text[:200]}...")
            
            response.raise_for_status()
            result = response.json()
            
            if result['status'] == 'success':
                # 儲存檔案內容供後續使用(統一變數名稱)
                if self.app_instance:
                    import time
                    self.app_instance.last_uploaded_file_content = result['content']
                    self.app_instance.uploaded_file_content = result['content']  # 統一變數名稱
                    self.app_instance.last_uploaded_filename = filename
                    self.app_instance.last_upload_time = time.time()
                    print(f"[DEBUG] 已保存上傳檔案內容,長度: {len(result['content'])},時間戳: {self.app_instance.last_upload_time}")
                    # 設置等待用戶回覆的標記
                    self.app_instance.waiting_for_file_action = True
                
                return f"""✅ 檔案上傳成功!

📁 檔案名稱: {filename}
📊 檔案大小: {len(result['content'])} 字元  
📝 檔案類型: {Path(filename).suffix or '未知'}

請問您想要做什麼?
• 分析重點 - 找出檔案中的關鍵信息
• 解題 - 解答檔案中的問題
• 寫心得 - 根據檔案內容寫感想
• 翻譯 - 翻譯檔案內容
• 總結 - 提供內容摘要
• 詳細分析 - 深入分析檔案內容

請直接告訴我您的需求!"""
            else:
                return f"檔案上傳失敗: {result['message']}"
    except requests.exceptions.ConnectionError:
        return "錯誤:無法連線到本地 API 服務。請確認伺服器已啟動。"
    except Exception as e:
        return f"檔案上傳時發生錯誤: {e}"

上傳流程詳細解析

1. 檔案驗證階段

if not file_path or not Path(file_path).exists():
    return "檔案路徑無效或檔案不存在"

filename = Path(file_path).name
print(f"[DEBUG] 準備上傳檔案: {filename}")

2. 檔案讀取與傳輸

with open(file_path, 'rb') as file:
    files = {'file': (filename, file, 'application/octet-stream')}
    print(f"[DEBUG] 發送請求到API...")
    response = requests.post(f"{LOCAL_API_BASE}/upload-file", files=files, timeout=30)

3. API 響應處理

print(f"[DEBUG] API響應狀態碼: {response.status_code}")
print(f"[DEBUG] API響應內容: {response.text[:200]}...")

response.raise_for_status()
result = response.json()

狀態管理系統

智能狀態保存機制

if result['status'] == 'success':
    if self.app_instance:
        import time
        self.app_instance.last_uploaded_file_content = result['content']
        self.app_instance.uploaded_file_content = result['content']  # 統一變數名稱
        self.app_instance.last_uploaded_filename = filename
        self.app_instance.last_upload_time = time.time()
        print(f"[DEBUG] 已保存上傳檔案內容,長度: {len(result['content'])},時間戳: {self.app_instance.last_upload_time}")
        # 設置等待用戶回覆的標記
        self.app_instance.waiting_for_file_action = True

狀態管理特色:

雙重內容保存

  • last_uploaded_file_content:最新上傳的檔案內容
  • uploaded_file_content:統一變數名稱確保相容性
  • 目的:確保不同工具都能正確存取檔案內容

metadata 記錄

  • last_uploaded_filename:保存原始檔案名稱
  • last_upload_time:精確記錄上傳時間戳
  • 目的:提供完整的檔案資訊供後續處理

工作流程控制

  • waiting_for_file_action:設定為 True 表示等待用戶指令
  • 目的:讓系統知道檔案已準備就緒,等待下一步操作

本地 API 整合架構

環境配置系統

LOCAL_API_BASE = os.environ.get("LOCAL_API_BASE", "http://127.0.0.1:8000")

配置特色:

  • 環境變數支援:支援不同環境的 API 端點配置
  • 預設值保護:提供預設的本地開發環境地址
  • 靈活部署:可以輕鬆切換到不同的 API 服務

FastAPI 服務對接

response = requests.post(f"{LOCAL_API_BASE}/upload-file", files=files, timeout=30)

對接特色:

  • RESTful API:使用標準的 POST 請求上傳檔案
  • 端點設計/upload-file 專門處理檔案上傳
  • 超時控制:30 秒超時確保不會無限等待
  • 錯誤隔離:網路問題不影響主程式運行

錯誤處理與用戶體驗

分層錯誤處理

except requests.exceptions.ConnectionError:
    return "錯誤:無法連線到本地 API 服務。請確認伺服器已啟動。"
except Exception as e:
    return f"檔案上傳時發生錯誤: {e}"

錯誤處理特色:

  • 網路錯誤特別處理:針對連線問題提供具體解決建議
  • 通用錯誤捕獲:捕獲所有其他異常並提供詳細資訊
  • 用戶友善訊息:錯誤訊息清楚說明問題和解決方向

成功回饋設計

return f"""✅ 檔案上傳成功!

📁 檔案名稱: {filename}
📊 檔案大小: {len(result['content'])} 字元  
📝 檔案類型: {Path(filename).suffix or '未知'}

請問您想要做什麼?
• 分析重點 - 找出檔案中的關鍵信息
• 解題 - 解答檔案中的問題
• 寫心得 - 根據檔案內容寫感想
• 翻譯 - 翻譯檔案內容
• 總結 - 提供內容摘要
• 詳細分析 - 深入分析檔案內容

請直接告訴我您的需求!"""

用戶體驗特色:

  • 視覺化圖示:使用 emoji 讓訊息更加直觀
  • 詳細資訊顯示:檔案名稱、大小、類型一目了然
  • 操作引導:提供明確的下一步操作選項
  • 互動式設計:引導用戶說出具體需求

與其他系統的整合

與內容生成系統整合

  • 上傳的檔案內容可以作為內容生成的參考資料
  • 生成的內容可以基於上傳檔案的風格和主題

與 Word 操作系統整合

  • 上傳檔案後的分析結果可以直接寫入 Word 文件
  • 形成從檔案讀取到分析到輸出的完整工作流

與專家分析系統整合

  • 為六大專家分析模式提供檔案內容
  • 確保每個專家都能存取到相同的檔案內容

效能優化與安全考量

效能優化策略

# 檔案大小監控
print(f"[DEBUG] 已保存上傳檔案內容,長度: {len(result['content'])}")

# 超時控制
response = requests.post(f"{LOCAL_API_BASE}/upload-file", files=files, timeout=30)

# 記憶體管理
# 檔案內容保存到實例變數而非全域變數

安全性考量

# 檔案存在性檢查
if not file_path or not Path(file_path).exists():
    return "檔案路徑無效或檔案不存在"

# 錯誤資訊控制
except Exception as e:
    return f"檔案上傳時發生錯誤: {e}"  # 不洩露敏感系統資訊

總結

檔案上傳系統是智能助手的「資料入口閘道」,它:

  • 提供穩定可靠的檔案上傳機制,支援多種格式的檔案處理
  • 建立完整的狀態管理系統,確保檔案內容在整個應用中正確流轉
  • 實現與本地 API 服務的無縫整合,提供強大的檔案解析能力
  • 提供優秀的用戶體驗,包含詳細的成功回饋和錯誤處理

這個系統為後續的智能分析奠定了堅實的基礎,讓 AI 助手能夠理解和處理用戶提供的各種文件資料。

下一篇,我們將深入探討六大專家分析系統,看看 AI 如何根據不同的專業領域提供深度分析服務。



上一篇
DAY 18
系列文
我的 AI 助手開發19
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言